package gu.sql2java.wherehelper;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.base.Strings.nullToEmpty;
import static com.google.common.base.MoreObjects.firstNonNull;
import static gu.sql2java.bean.BeanPropertyUtils.isEmpty;
import static gu.sql2java.bean.BeanPropertyUtils.allEmpty;
import static gu.sql2java.SimpleLog.log;
import static gu.sql2java.wherehelper.VarTestType.checkVarTestType;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.io.Resources;

import gu.sql2java.BaseBean;
import gu.sql2java.BaseRow;
import gu.sql2java.wherehelper.annotations.BitTest;
import gu.sql2java.wherehelper.annotations.Compare;
import gu.sql2java.wherehelper.annotations.EnableWhereHelper;
import gu.sql2java.wherehelper.annotations.Equal;
import gu.sql2java.wherehelper.annotations.EqualIf;
import gu.sql2java.wherehelper.annotations.Expression;
import gu.sql2java.wherehelper.annotations.GroupBy;
import gu.sql2java.wherehelper.annotations.IfElse;
import gu.sql2java.wherehelper.annotations.Like;
import gu.sql2java.wherehelper.annotations.OrderBy;
import gu.sql2java.wherehelper.annotations.Range;


/**
 * 基于调用者提供的表达式生成动态执行脚本(BeanShell)
 * @author guyadong
 *
 */
public class BeanShellWhereBuilder{
	/*****************************************/
	/** 脚本模板名称定义                         **/
	/*****************************************/	
	private static final String TMPL_EQUAL = "equal.tmpl";
	private static final String TMPL_BIT_TEST = "bit_test.tmpl";
	private static final String TMPL_EQUAL_IF = "equal_if.tmpl";
	private static final String TMPL_IF_ELSE = "if_else.tmpl";
	private static final String TMPL_LIKE = "like.tmpl";
	private static final String TMPL_COMPARE = "compare.tmpl";
	private static final String TMPL_GROUP_BY = "group_by.tmpl";
	private static final String TMPL_ORDER_BY = "order_by.tmpl";
	private static final String TMPL_EXP = "exp.tmpl";
	private static final String TMPL_LIMIT = "limit.tmpl";
	private static final String TMPL_BEFORE_COND = "before_cond.tmpl";
	private static final String TMPL_AFTER_COND = "after_cond.tmpl";
    public static final String NOT_EQUAL = "$<NOT_EQUAL>";
    public static final String OR_NULL = "$<OR_NULL>";
    public static final String BIT_OR = "$<BIT_OR>";
    public static final String IGNORE_EMPTY = "$<IGNORE_EMPTY>";
	private static final String AND_OR = "$<AND_OR>";
	private static final String TEST = "$<TEST>";
	private static final String AGG_FUN = "$<AGG_FUN>";
	private static final String DEFAULT_ORDER_BY_VAR = "order_by_column";
	private static final String DEFAULT_GROUP_BY_VAR = "group_by_column";
	public static final String KEYWORD_COND_COUNT = "cond_count";
	public static final String KEYWORD_WHERE_BUFFER = "where_buffer";
	public static final String KEYWORD_EXP_BUFFER = "cond_buffer";
	public static final String DT_MYSQL="MySQL";
	private static class Tmpls{		
		/**
		 * 模板名-动态脚本模板内容映射
		 */
		private final static ImmutableMap<String, String> tmpls = loadAllTemplates();
	}
	private String selectFrom = "";
	private String andor = "AND";
	/**
	 * 所有imoprt导入语句
	 */
	private List<String> importLines = Lists.newLinkedList();
	/**
	 * 所有表达式的bsh脚本
	 */
	private List<String> conditionCodes = Lists.newLinkedList();
	private List<String> orderByColumns = Lists.newLinkedList();
	private List<String> groupByColumns = Lists.newLinkedList();
	/**
	 * SQL 类型,目前只支持MySQL
	 */
	private String sqltype = DT_MYSQL;
	/**
	 * 是否输出调试日志
	 */
	private boolean debuglog = false;
	/**
	 * 是否生成分页查询语句
	 */
	private boolean pagequery = true;
	/**
	 * 输入参数的目标表对象,默认为 {@link BaseBean}
	 */
	private Class<? extends BaseRow> targetClass = BaseRow.class;
	/**
	 * 引用变量名列表
	 */
	private Set<String> referenceVariables;
	/**
	 * 变量字段名对应的类型映射
	 */
	private Map<String, Class<?>> varTypes = Collections.emptyMap();
	private String orderByVarname = DEFAULT_ORDER_BY_VAR;
	private String groupByVarname = DEFAULT_GROUP_BY_VAR;
	BeanShellWhereBuilder(){
	}
	
	public boolean debuglog() {
		return debuglog;
	}

	/**
	 * 设置是否输出调试信息
	 * @param debuglog
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder debuglog(boolean debuglog) {
		this.debuglog = debuglog;
		return this;
	}

	/**
	 * 设置是否支持生成分页查询语句(如MySQL LIMIT ${row_count}  OFFSET ${offset})
	 * @param pagequery
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder pagequery(boolean pagequery){
		this.pagequery = pagequery;
		return this;
	}
	public Set<String> getReferenceVariables() {
		return referenceVariables;
	}

	public Class<? extends BaseRow> getTargetClass() {
		return targetClass;
	}

	public Map<String, Class<?>> getVarTypes() {
		return varTypes;
	}

	/**
	 * @return orderByVarname
	 */
	public String getOrderByVarname() {
		return orderByVarname;
	}

	/**
	 * @return groupByVarname
	 */
	public String getGroupByVarname() {
		return groupByVarname;
	}

	/**
	 * @return orderByColumns
	 */
	public String getOrderByColumns() {
		return Joiner.on(',').join(orderByColumns);
	}

	/**
	 * @return groupByColumns
	 */
	public String getGroupByColumns() {
		return Joiner.on(',').join(groupByColumns);
	}

	/**
	 * 生成一般表达式
	 * @param exp
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder exp(String exp){
		exp = nullToEmpty(exp).trim();
		if(!isNullOrEmpty(exp)) {
			conditionCodes.add(Tmpls.tmpls.get(TMPL_EXP)
					.replace(AND_OR, andor)
					.replace("$<exp>", exp)	);
		}
		return this;
	}
	/**
	 * 指定与前一个表达式的连接方式为OR
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder or(){
		andor = "OR";
		return this;
	}
	/**
	 * 指定与前一个表达式的连接方式为AND
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder and(){
		andor = "AND";
		return this;
	}
	/**
	 * 参见{@link #equal(String)},不之处在于如果column_name为{@code null}或空则忽略,不生成表达式
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field
	 * @param not 为{@code true}执行不等价比较
	 * @param notCheckEmpty 为{@code true} 不检查字段是否为{@code null}或空
	 * @param orNull 为{@code true}输出等价或为NULL表达式，例如 (left=value OR left IS NULL)
	 * @return 当前对象
	 */
	private BeanShellWhereBuilder equal(String left,String field, boolean not, boolean notCheckEmpty, boolean orNull){
		if(!isNullOrEmpty(field)) {
			conditionCodes.add(Tmpls.tmpls.get(TMPL_EQUAL)
					.replace(NOT_EQUAL, "" + not)
					.replace(IGNORE_EMPTY, "" + notCheckEmpty)
					.replace(OR_NULL, "" + orNull)
					.replace(AND_OR, andor)
					.replace("$<field>", field)
					.replace("$<left>", column(left,field)));
		}
		return this;
	}

	/**
	 * 创建等价表达式，如{@code  column_name = $<column_name>},<br>
	 * 如果column_name为{@code null}或空,则表达式为 {@code  column_name IS NULL}<br>
	 * 如果column_name为集合,则为IN表达式 {@code  column_name IN (...)}<br>
	 * @param field
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder equal(String field){
		return equal(null,field,false, true, false);
	}
	/**
	 * @param left
	 * @param field
	 * @since 3.17.5
	 */
	public BeanShellWhereBuilder equal(String left, String field){
	    return equal(left,field,false, true, false);
	}
	/**
	 * 创建一个不等价表达式，如{@code  column_name != $<column_name>},<br>
	 * 如果column_name为{@code null}或空,则表达式为 {@code  column_name IS NOT NULL}<br>
	 * 如果column_name为集合,则为IN表达式 {@code  column_name NOT IN (...)}<br>
	 * @param field
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder equalNot(String field){
		return equal(null,field,true, true, false);
	}
	public BeanShellWhereBuilder equalNot(String left,String field){
	    return equal(left,field,true, true, false);
	}
	/**
	 * 创建等价或为NULL表达式，
	 * 如{@code  column_name = $<column_name> OR column_name IS NULL},<br>
	 * @param field
	 * @return 当前对象
	 * @since 3.26.0
	 */
	public BeanShellWhereBuilder equalOrNull(String field){
		return equal(null,field,false, false, true);
	}
	/**
	 * @param left
	 * @param field
	 * @since 3.26.0
	 */
	public BeanShellWhereBuilder equalOrNull(String left,String field){
		return equal(left,field,false, false, true);
	}
	/**
	 * 参见{@link #equal(String)},不之处在于如果column_name为{@code null}或空则忽略,不生成表达式
	 * @param field
	 * @param not 为{@code true}执行不等价比较
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder equalIfNonEmpty(String field, boolean not){
		return equal(null,field,not, false, false);
	}
	/**
	 * @param left
	 * @param field
	 * @param not
	 * @return 当前对象
	 * @since 3.17.5
	 */
	public BeanShellWhereBuilder equalIfNonEmpty(String left, String field, boolean not){
	    return equal(left,field,not, false, false);
	}
	/**
	 * 参见{@link #equal(String)},不之处在于如果column_name为{@code null}或空则忽略,不生成表达式
	 * @param field
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder equalIfNonEmpty(String field){
		return equal(null,field,false, false, false);
	}
	/**
	 * @param left
	 * @param field
	 * @return 当前对象
	 * @since 3.17.5
	 */
	public BeanShellWhereBuilder equalIfNonEmpty(String left,String field){
	    return equal(left,field,false, false, false);
	}
	/**
	 * 当满足{@code test}指定的条件时,创建等价表达式<br>
	 * 输入参数为{@code null}或空则忽略,不生成表达式
	 * @param test 判断条件
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 字段名
	 * @param not 为{@code true}执行不等价比较
	 * @param notCheckEmpty 为{@code true} 不检查字段是否为{@code null}或空
	 * @return 当前对象
	 * @see #equal(String)
	 * @since 3.17.5
	 */
	public BeanShellWhereBuilder equalIf(String test,String left,String field,boolean not, boolean notCheckEmpty){
		if(!isNullOrEmpty(test) && !isNullOrEmpty(field)) {
			conditionCodes.add(Tmpls.tmpls.get(TMPL_EQUAL_IF)
					.replace(NOT_EQUAL, "" + not)
					.replace(IGNORE_EMPTY, "" + notCheckEmpty)
					.replace(AND_OR, andor)
					.replace("$<TEST>", test)
					.replace("$<field>", field)
					.replace("$<left>", column(left,field)));
		}
		return this;
	}

	/**
	 * 当满足{@code test}指定的条件以及{@code testNullVars,testNonullVars,testEmptyVars,testNoEmptyVars,testTrueVars,testFalseVars}指定变量满足条件时,创建等价表达式<br>
	 * 输入参数为{@code null}或空则忽略,不生成表达式
	 * @param test 判断条件
	 * @param testNullVars 要求为{@code null}的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为{@code null}或空则默认为'true'
	 * @param testNonullVars 要求不为{@code null}的变量名列表,['var1','var2'],等价于'null!=${var1} && null!=${var2}',为{@code null}或空则默认为'true'
	 * @param testEmptyVars 要求为{@code null}或空的变量名列表,['var1','var2'],等价于'isEmpty(${var1}) && isEmpty(${var2})',为{@code null}或空则默认为'true'
	 * @param testNoEmptyVars 要求不为{@code null}或空的变量名列表,['var1','var2'],等价于'!isEmpty(${var1}) && !isEmpty(${var2})',为{@code null}或空则默认为'true'
	 * @param testTrueVars 要求为{@code true}的变量名列表,['var1','var2'],等价于'isTrue(${var1)} && isTrue(${var2})',为空则默认为'true'
	 * @param testFalseVars 要求为{@code false}的变量名列表,['var1','var2'],等价于'isFalse(${var1}) && isFalse(${var2})',为空则默认为'true'
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field
	 * @param not 为{@code true}执行不等价比较
	 * @param notCheckEmpty 为{@code true} 不检查字段是否为{@code null}或空
	 * @return 当前对象
	 * @see #equalIf(String, String, String, boolean, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder equalIf(String test,
			String[] testNullVars,String[] testNonullVars,String[] testEmptyVars, String[] testNoEmptyVars, 
			String[] testTrueVars, String[] testFalseVars, String left, String field, boolean not, boolean notCheckEmpty){
		return equalIf(buildTestExps(test, testNullVars, testNonullVars, testEmptyVars, testNoEmptyVars, testTrueVars, testFalseVars), 
				left, field, not, notCheckEmpty);
	}

	/**
	 * 当满足{@code test}指定的条件时,创建等价表达式<br>
	 * 输入参数为{@code null}或空则忽略,不生成表达式
	 * @param test 判断条件
	 * @param field
	 * @param not 为{@code true}执行不等价比较
	 * @param notCheckEmpty 为{@code true} 不检查字段是否为{@code null}或空
	 * @return 当前对象
	 * @see #equalIf(String, String, String, boolean, boolean)
	 */
	public BeanShellWhereBuilder equalIf(String test,String field,boolean not, boolean notCheckEmpty){
		return equalIf(test,field,field,not, notCheckEmpty);
	}
	/**
	 * 当满足{@code test}指定的条件时,创建等价表达式<br>
	 * 输入参数为{@code null}或空则忽略,不生成表达式
	 * @param test 判断条件
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field
	 * @param not 为{@code true}执行不等价比较
	 * @return 当前对象
	 * @see #equalIf(String, String, String, boolean, boolean)
	 * @since 3.17.5
	 */
	public BeanShellWhereBuilder equalIf(String test,String left,String field,boolean not){
		return equalIf(test,left,field,not, false);
	}
	
	/**
	 * 当满足{@code test}指定的条件时,创建等价表达式<br>
	 * 输入参数为{@code null}或空则忽略,不生成表达式
	 * @param test 判断条件
	 * @param field
	 * @param not 为{@code true}执行不等价比较
	 * @return 当前对象
	 * @see #equalIf(String, String, String, boolean, boolean)
	 */
	public BeanShellWhereBuilder equalIf(String test,String field,boolean not){
		return equalIf(test,field,field,not, false);
	}
	/**
	 * 根据{@code testType}指定的类型测试{@code testVars} 指定的变量所有变量都满足条件,则创建等价表达式<br>
	 * {@code testVars,testType}为{@code null}或空视为{@code true},
	 * 输入参数为{@code null}或空则忽略,不生成表达式
	 * @param testVars 要求为null的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为{@code null}或空则默认为'true'
	 * @param testType
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field
	 * @param not 为{@code true}执行不等价比较
	 * @param notCheckEmpty 为{@code true} 不检查字段是否为{@code null}或空
	 * @return 当前对象
	 * @see #equalIf(String, String, String, boolean, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder equalIf(String[] testVars,VarTestType testType, String left, String field, boolean not, boolean notCheckEmpty){
		return equalIf(renderVars(testVars, testType),left,field,not, notCheckEmpty);
	}
	/**
	 * 根据{@code testType}指定的类型测试{@code testVars} 指定的变量所有变量都满足条件,则创建等价表达式<br>
	 * {@code testVars,testType}为{@code null}或空视为{@code true},
	 * 输入参数为{@code null}或空则忽略,不生成表达式
	 * @param testVars 要求为null的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为{@code null}或空则默认为'true'
	 * @param testType
	 * @param field
	 * @param not 为{@code true}执行不等价比较
	 * @param notCheckEmpty 为{@code true} 不检查字段是否为{@code null}或空
	 * @return 当前对象
	 * @see #equalIf(String, String, String, boolean, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder equalIf(String[] testVars,VarTestType testType,String field, boolean not, boolean notCheckEmpty){
		return equalIf(renderVars(testVars, testType),null,field,not, notCheckEmpty);
	}
	/**
	 * 根据{@code testType}指定的类型测试{@code testVar} 指定的变量满足条件,则创建等价表达式<br>
	 * {@code field,testType}为{@code null}或空视则忽略,不生成表达式
	 * @param testVar 条件测试表达式变量名,为{@code null}或空则默认为{@code field}
	 * @param testType 变量测试类型
	 * @param testOp 条件测试操作符
	 * @param testValue 变量条件测试的目标值 
	 * @param testQuote 为{@code true}生成表达式对{@code testValue} 以字符串对头尾增加单引号,{@code refValue}为{@code true}时忽略
	 * @param testRefValue 为{@code true}生成表达式对{@code testValue} 视为变量名
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 创建等价表达式的字段名
	 * @param not 为{@code true}执行不等价比较
	 * @param notCheckEmpty 为{@code true} 不检查字段是否为{@code null}或空
	 * @return 当前对象
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder equalIf(String testVar,VarTestType testType,CompareOp testOp, Object testValue,boolean testQuote,boolean testRefValue, 
			String left,String field,boolean not, boolean notCheckEmpty){
		String test = buildTestVarExp(testVar, testType, testOp, testValue, testQuote, testRefValue, field);
		if(!test.isEmpty()) {
			return equalIf(test,left,left,not,notCheckEmpty);
		}
		return this;
	}
	/**
	 * 创建位运算比较表达式，如{@code  (column_name & 100) = $<column_name>},<br>
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field
	 * @param bitOr 为{@code true}执行OR运算
	 * @param notCheckEmpty 为{@code true} 不检查字段是否为{@code null}或空
	 * @param aggFun 自定义参数聚合实现类
	 * @return 当前对象
	 * @since 3.27.0
	 */
	@SuppressWarnings("rawtypes")
	BeanShellWhereBuilder bitTest(String left,String field, boolean bitOr, boolean notCheckEmpty,Class<? extends BitAggFun>  aggFun){
		if(!isNullOrEmpty(field)) {
			conditionCodes.add(Tmpls.tmpls.get(TMPL_BIT_TEST)
					.replace(BIT_OR, "" + bitOr)
					.replace(IGNORE_EMPTY, "" + notCheckEmpty)
					.replace(AND_OR, andor)
					.replace(AGG_FUN, null == aggFun ||  BitAggFun.class.equals(aggFun) ? "null" :aggFun.getName()+".class")
					.replace("$<field>", field)
					.replace("$<left>", column(left,field)));
		}
		return this;
	}
	/**
	 * 创建位运算比较表达式，如{@code  (column_name & 100) = $<column_name>},<br>
	 * @param field
	 * @return 当前对象
	 * @since 3.27.0
	 * @see #bitTest(String, String, boolean, boolean, Class)
	 */
	public BeanShellWhereBuilder bitTest(String field){
		return bitTest(null,field,false, false, null);
	}
	/**
	 * 创建位运算比较表达式，如{@code  (column_name & 100) = $<column_name>},<br>
	 * @param field
	 * @param aggFun 
	 * @return 当前对象
	 * @see #bitTest(String, String, boolean, boolean, Class)
	 * @since 3.27.0
	 */
	@SuppressWarnings("rawtypes")
	public BeanShellWhereBuilder bitTest(String field,Class<? extends BitAggFun>  aggFun){
		return bitTest(null,field,false, false, aggFun);
	}
	/**
	 * 创建位运算比较表达式，如{@code  (column_name & 100) = $<column_name>},<br>
	 * @param left
	 * @param field
	 * @return 当前对象
	 * @see #bitTest(String, String, boolean, boolean, Class)
	 * @since 3.27.0
	 */
	public BeanShellWhereBuilder bitTest(String left, String field){
	    return bitTest(left,field,false, false, null);
	}
	/**
	 * 创建位运算比较表达式，如{@code  (column_name & 100) = $<column_name>},<br>
	 * @param left
	 * @param field
	 * @param aggFun 
	 * @return 当前对象
	 * @see #bitTest(String, String, boolean, boolean, Class)
	 * @since 3.27.0
	 */
	@SuppressWarnings("rawtypes")
	public BeanShellWhereBuilder bitTest(String left, String field,Class<? extends BitAggFun>  aggFun){
		return bitTest(left,field,false, false, aggFun);
	}
	/**
	 * 输入条件{@code test}为{@code true}则生成{@code doStatement}指定的表达式,
	 * 否则生成{@code elseStatement}指定的表达式,{@code elseStatement}为{@code null}时不生成表达式
	 * @param test 判断条件
	 * @param doStatement 判断条件为真时的执行语句
	 * @param elseStatement 判断条件为假时的执行语句,为{@code null}忽略
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder ifelse(String test,String doStatement,String elseStatement){
		if(!isNullOrEmpty(test) && !isNullOrEmpty(doStatement)) {
			elseStatement = nullToEmpty(elseStatement);
			conditionCodes.add(Tmpls.tmpls.get(TMPL_IF_ELSE)
					.replace(AND_OR, andor)
					.replace("$<TEST>", test)
					.replace("$<THEN>", doStatement)
					.replace("$<ELSE>", elseStatement));
		}
		return this;
	}
	/**
	 * 当满足{@code test}指定的条件以及{@code testNullVars,testNonullVars,testEmptyVars,testNoEmptyVars,testTrueVars,testFalseVars}指定变量满足条件时
	 * 则生成{@code doStatement}指定的表达式,
	 * 否则生成{@code elseStatement}指定的表达式,{@code elseStatement}为{@code null}时不生成表达式,
	 * {@code test,testNullVars,testNonullVars,testEmptyVars,testNoEmptyVars,testTrueVars,testFalseVars}都为空时忽略
	 * @param test 判断条件
	 * @param testNullVars 要求为{@code null}的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为{@code null}或空则默认为'true'
	 * @param testNonullVars 要求不为{@code null}的变量名列表,['var1','var2'],等价于'null!=${var1} && null!=${var2}',为{@code null}或空则默认为'true'
	 * @param testEmptyVars 要求为{@code null}或空的变量名列表,['var1','var2'],等价于'isEmpty(${var1}) && isEmpty(${var2})',为{@code null}或空则默认为'true'
	 * @param testNoEmptyVars 要求不为{@code null}或空的变量名列表,['var1','var2'],等价于'!isEmpty(${var1}) && !isEmpty(${var2})',为{@code null}或空则默认为'true'
	 * @param testTrueVars 要求为{@code true}的变量名列表,['var1','var2'],等价于'isTrue(${var1)} && isTrue(${var2})',为空则默认为'true'
	 * @param testFalseVars 要求为{@code false}的变量名列表,['var1','var2'],等价于'isFalse(${var1}) && isFalse(${var2})',为空则默认为'true'
	 * @param doStatement 判断条件为真时的执行语句
	 * @param elseStatement 判断条件为假时的执行语句,为{@code null}忽略
	 * @return 当前对象
	 * @see #ifelse(String, String, String)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder ifelse(String test,
			String[] testNullVars,String[] testNonullVars,String[] testEmptyVars, String[] testNoEmptyVars, 
			String[] testTrueVars,String[] testFalseVars, String doStatement, String elseStatement){
		if(allEmpty(test,testNullVars,testNonullVars,testEmptyVars,testNoEmptyVars,testTrueVars,testFalseVars)) {
			return this;
		}
		return ifelse(buildTestExps(test, testNullVars, testNonullVars, testEmptyVars, testNoEmptyVars, testTrueVars, testFalseVars), 
				doStatement,elseStatement);
	}

	/**
	 * 根据{@code testType}指定的类型测试{@code testVars} 指定的变量所有变量都满足条件,
	 * 则生成{@code doStatement}指定的表达式,
	 * 否则生成{@code elseStatement}指定的表达式,{@code elseStatement}为{@code null}时不生成表达式,
	 * {@code testVars,testType}为{@code null}或空视为{@code true},
	 * @param testVars 要求为null的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为{@code null}或空则默认为'true'
	 * @param testType 操作数为1的测试类型
	 * @param doStatement 判断条件为真时的执行语句
	 * @param elseStatement 判断条件为假时的执行语句,为{@code null}忽略
	 * @return 当前对象
	 * @see #ifelse(String, String, String)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder ifelse(String[] testVars,VarTestType testType, String doStatement,String elseStatement){
		return ifelse(renderVars(testVars, checkVarTestType(testType,1)),doStatement,elseStatement);
	}
	/**
	 * 生成对变量{@code testVar}的测试表达式if... else语句，表达式为{@code true}则生成{@code doStatement}指定的表达式,
	 * 否则生成{@code elseStatement}指定的表达式,{@code elseStatement}为{@code null}时不生成表达式
	 * @param testVar 条件测试表达式变量名
	 * @param testType 变量测试类型
	 * @param testOp 条件测试操作符
	 * @param testValue 变量条件测试的目标值 
	 * @param testQuote 为{@code true}生成表达式对{@code testValue} 以字符串对头尾增加单引号,{@code refValue}为{@code true}时忽略
	 * @param testRefValue 为{@code true}生成表达式对{@code testValue} 视为变量名
	 * @param doStatement 判断条件为真时的执行语句
	 * @param elseStatement 判断条件为假时的执行语句,为{@code null}忽略
	 * @return 当前对象
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder testVar(String testVar,VarTestType testType,CompareOp testOp, Object testValue,boolean testQuote,boolean testRefValue, String doStatement,String elseStatement){
		if(!isNullOrEmpty(testVar) && null != testType && !isNullOrEmpty(doStatement)) {
			String test = testType.render(testVar, testOp, testValue, testQuote,testRefValue);
			return ifelse(test,doStatement,elseStatement);
		}
		return this;
	}
	/**
	 * 生成对变量{@code testVar}的测试表达式if语句，表达式为{@code true}则生成{@code doStatement}指定的表达式,
	 * @param testVar
	 * @param testType 操作数为3的测试类型
	 * @param testOp
	 * @param testValue
	 * @param testQuote
	 * @param testRefValue
	 * @param doStatement
	 * @see #testVar(String, VarTestType, CompareOp, Object, boolean, boolean, String, String)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder testVar(String testVar,VarTestType testType,CompareOp testOp, Object testValue,boolean testQuote,boolean testRefValue, String doStatement){
		return testVar(testVar,checkVarTestType(testType,3),testOp,testValue,testQuote,testRefValue,doStatement,null);
	}
	/**
	 * 生成对变量{@code testVar}的测试表达式if语句，表达式为{@code true}则生成{@code doStatement}指定的表达式,
	 * @param testVar
	 * @param testType 操作数为3的测试类型
	 * @param testOp
	 * @param testValue
	 * @param doStatement
	 * @see #testVar(String, VarTestType, CompareOp, Object, boolean, boolean, String, String)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder testVar(String testVar,VarTestType testType,CompareOp testOp, Object testValue,String doStatement){
		return testVar(testVar,checkVarTestType(testType,3),testOp,testValue,false,false,doStatement,null);
	}
	/**
	 * 生成对变量{@code testVar}的测试表达式if语句，表达式为{@code true}则生成{@code doStatement}指定的表达式,
	 * @param testVar
	 * @param testType 操作数为2的测试类型
	 * @param testValue
	 * @param testQuote
	 * @param testRefValue
	 * @param doStatement
	 * @see #testVar(String, VarTestType, CompareOp, Object, boolean, boolean, String, String)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder testVar(String testVar,VarTestType testType,Object testValue,boolean testQuote,boolean testRefValue,String doStatement){
		return testVar(testVar,checkVarTestType(testType,2),null,testValue,testQuote,testRefValue,doStatement,null);
	}
	/**
	 * 生成对变量{@code testVar}的测试表达式if语句，表达式为{@code true}则生成{@code doStatement}指定的表达式,
	 * @param testVar
	 * @param testType 操作数为2的测试类型
	 * @param testValue
	 * @param doStatement
	 * @see #testVar(String, VarTestType, CompareOp, Object, boolean, boolean, String, String)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder testVar(String testVar,VarTestType testType,Object testValue,String doStatement){
		return testVar(testVar,checkVarTestType(testType,2),null,testValue,false,false,doStatement,null);
	}
	/**
	 * 生成对变量{@code testVar}的测试表达式if语句，表达式为{@code true}则生成{@code doStatement}指定的表达式,
	 * @param testVar 
	 * @param testType 操作数为1的测试类型
	 * @param doStatement
	 * @see #testVar(String, VarTestType, CompareOp, Object, boolean, boolean, String, String)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder testVar(String testVar,VarTestType testType,String doStatement){
		return testVar(testVar,checkVarTestType(testType,1),null,null,false,false,doStatement,null);
	}

	/**
	 * 同{@link #ifelse(String, String, String)},只是没有{@code elseStatement}
	 * @param test 判断条件
	 * @param doStatement 判断条件为真时的执行语句
	 * @return 当前对象
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder onlyif(String test,String doStatement){
		return ifelse(test, doStatement, null);
	}
	/**
	 * 同{@link #ifelse(String, String[], String[], String[], String[], String[], String[], String, String)},只是没有{@code elseStatement}
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder onlyif(String test,
			String[] testNullVars,String[] testNonullVars,
			String[] testEmptyVars, String[] testNoEmptyVars, 
			String[] testTrueVars,String[] testFalseVars,
			String doStatement){
		if(allEmpty(test,testNullVars,testNonullVars,testEmptyVars,testNoEmptyVars,testTrueVars,testFalseVars)) {
			return this;
		}
		return ifelse(buildTestExps(test, testNullVars, testNonullVars, testEmptyVars, testNoEmptyVars, testTrueVars, testFalseVars), doStatement, null);
	}
	/**
	 * 同{@link #ifelse(String[], VarTestType, String, String)},只是没有{@code elseStatement}
	 * @param testVars
	 * @param testType 操作数为1的测试类型
	 * @param doStatement
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder onlyif(String[] testVars,VarTestType testType,
			String doStatement){
		return ifelse(renderVars(testVars, checkVarTestType(testType,1)), doStatement, null);
	}
	/**
	 * 创建模糊匹配表达式，如{@code  column_name LIKE '%$<column_name>%'}<br>
	 * @param test 判断条件,条件为'true'则生成LIKE表达式,为{@code null}或空则默认为'true'
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param likeOp 模糊匹配方式
	 * @param refValue 为{@code true}或{@code left}为{@code null}或空生成表达式对{@code field} 视为变量名,否则视为常量
	 * @return 当前对象
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder like(String test,
			String left,String field,LikeOp likeOp, boolean refValue){
		if(!isNullOrEmpty(field)) {
			checkValidLeft(refValue,left);
			conditionCodes.add(Tmpls.tmpls.get(TMPL_LIKE)
					.replace(AND_OR, andor)
					.replace("${$<field>}", (isNullOrEmpty(left) ||  refValue)?"${$<field>}":JSON.toJSONString(field))
					.replace("$<left>", column(left,field))
					.replace("$<field>", field)
	                .replace(TEST, isNullOrEmpty(test)?"true":test)
					.replace("$<LIKE_OP>", firstNonNull(likeOp,LikeOp.DEFAULT).name()));
		}
		return this;
	}
	/**
	 * 创建模糊匹配表达式，如{@code  column_name LIKE '%$<column_name>%'}<br>
	 * @param test 判断条件,条件为'true'则生成LIKE表达式,为{@code null}或空则默认为'true'
	 * @param testNullVars 要求为{@code null}的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为{@code null}或空则默认为'true'
	 * @param testNonullVars 要求不为{@code null}的变量名列表,['var1','var2'],等价于'null!=${var1} && null!=${var2}',为{@code null}或空则默认为'true'
	 * @param testEmptyVars 要求为{@code null}或空的变量名列表,['var1','var2'],等价于'isEmpty(${var1}) && isEmpty(${var2})',为{@code null}或空则默认为'true'
	 * @param testNoEmptyVars 要求不为{@code null}或空的变量名列表,['var1','var2'],等价于'!isEmpty(${var1}) && !isEmpty(${var2})',为{@code null}或空则默认为'true'
	 * @param testTrueVars 要求为{@code true}的变量名列表,['var1','var2'],等价于'isTrue(${var1)} && isTrue(${var2})',为空则默认为'true'
	 * @param testFalseVars 要求为{@code false}的变量名列表,['var1','var2'],等价于'isFalse(${var1}) && isFalse(${var2})',为空则默认为'true'
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param likeOp 模糊匹配方式
	 * @param refValue 为{@code true}生成表达式对{@code field} 视为变量名,否则视为常量
	 * @return 当前对象
	 * @see #like(String, String, String, LikeOp, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder like(String test,
			String[] testNullVars,String[] testNonullVars,String[] testEmptyVars, String[] testNoEmptyVars, 
			String[] testTrueVars, String[] testFalseVars, String left, String field, LikeOp likeOp, boolean refValue){
		return like(buildTestExps(test, testNullVars, testNonullVars, testEmptyVars, testNoEmptyVars, testTrueVars, testFalseVars),left,field,likeOp, refValue);
	}
	/**
	 * 创建模糊匹配表达式，如{@code  column_name LIKE '%$<column_name>%'}<br>
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param likeOp 模糊匹配方式
	 * @param refValue 为{@code true}生成表达式对{@code field} 视为变量名,否则视为常量
	 * @return 当前对象
	 * @see #like(String, String, String, LikeOp, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder like(String left,String field,LikeOp likeOp,boolean refValue){
		return like(null,left,field,likeOp, refValue);
	}
	/**
	 * 创建两侧模糊匹配表达式，如{@code  column_name LIKE '%$<column_name>%'}<br>
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param refValue 为{@code true}或{@code left}为{@code null}或空生成表达式对{@code field} 视为变量名,否则视为常量
	 * @return 当前对象
	 * @see #like(String, String, String, LikeOp, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder like(String left,String field, boolean refValue){
		return like(null,left,field,LikeOp.DEFAULT,refValue);
	}
	/**
	 * 创建两侧模糊匹配表达式，如{@code  column_name LIKE '%$<column_name>%'}<br>
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 变量名,不为null或空，否则忽略
	 * @return 当前对象
	 * @see #like(String, String, String, LikeOp, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder like(String left,String field){
		return like(null,left,field,LikeOp.DEFAULT,true);
	}
	/**
	 * 创建两侧模糊匹配表达式，如{@code  column_name LIKE '%$<column_name>%'}<br>
	 * @param field 变量名,不为null或空，否则忽略
	 * @return 当前对象
	 * @see #like(String, String, String, LikeOp, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder like(String field){
		return like(null,null,field,LikeOp.DEFAULT,true);
	}
	/**
	 * 如果{@code test} 定义的表达式为{@code true}} ,则创建条件执行的两侧模糊匹配表达式，如{@code  column_name LIKE '%$<column_name>%'}<br>
	 * @param test 判断条件,条件为'true'则生成LIKE表达式,为{@code null}或空则不创建表达式
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param likeOp 模糊匹配方式
	 * @param refValue 为{@code true}生成表达式对{@code field} 视为变量名,否则视为常量
	 * @return 当前对象
	 * @see #like(String, String, String, LikeOp, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder likeIf(String test,String left,String field, LikeOp likeOp, boolean refValue){
		if(!isNullOrEmpty(test)) {
			return like(test,left,field,likeOp, refValue);
		}
		return this;
	}
	/**
	 * 如果{@code test} 定义的表达式为{@code true}} ,则创建条件执行的两侧模糊匹配表达式，如{@code  column_name LIKE '%$<column_name>%'}<br>
	 * @param test 判断条件,条件为'true'则生成LIKE表达式,为{@code null}或空则不创建表达式
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param refValue 为{@code true}生成表达式对{@code field} 视为变量名,否则视为常量
	 * @return 当前对象
	 * @see #like(String, String, String, LikeOp, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder likeIf(String test,String left,String field, boolean refValue){
		return likeIf(test,left,field,LikeOp.DEFAULT, refValue);
	}

	/**
	 * 创建条件执行的两侧模糊匹配表达式，如{@code  column_name LIKE '%$<column_name>%'}<br>
	 * @param test 判断条件,条件为'true'则生成LIKE表达式,为{@code null}或空则不创建表达式
	 * @param field 变量名,不为null或空，否则忽略
	 * @return 当前对象
	 * @see #like(String, String, String, LikeOp, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder likeIf(String test,String field){
		return likeIf(test,null,field,LikeOp.DEFAULT, true);
	}
	/**
	 * 根据{@code testType}指定的类型测试{@code testVars} 指定的变量所有变量都满足条件,则创建模糊匹配表达式，如{@code  column_name LIKE '%$<column_name>%'}<br>
	 * {@code testVars,testType}为{@code null}或空则不创建表达式
	 * @param testVars 要求为null的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为{@code null}或空则默认为'true'
	 * @param testType 变量测试类型
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param likeOp 模糊匹配方式
	 * @param refValue 为{@code true}生成表达式对{@code field} 视为变量名,否则视为常量
	 * @return 当前对象
	 * @see #likeIf(String, String, String, LikeOp, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder likeIf(String[] testVars,VarTestType testType, String left,String field,LikeOp likeOp, boolean refValue){
		return likeIf(renderVars(testVars, testType),left,field,likeOp, refValue);
	}
	/**
	 * 根据{@code testType}指定的类型测试{@code testVars} 指定的变量所有变量都满足条件,则创建模糊匹配表达式，如{@code  column_name LIKE '%$<column_name>%'}<br>
	 * {@code testVars,testType}为{@code null}或空则不创建表达式
	 * @param testVars 要求为null的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为{@code null}或空则默认为'true'
	 * @param testType 变量测试类型
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param likeOp 模糊匹配方式
	 * @return 当前对象
	 * @see #likeIf(String, String, String, LikeOp, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder likeIf(String[] testVars,VarTestType testType, String left,String field,LikeOp likeOp){
		return likeIf(renderVars(testVars, testType),left,field,likeOp, true);
	}
	/**
	 * 根据{@code testType}指定的类型测试{@code testVars} 指定的变量所有变量都满足条件,则创建模糊匹配表达式，如{@code  column_name LIKE '%$<column_name>%'}<br>
	 * {@code testVars,testType}为{@code null}或空则不创建表达式
	 * @param testVars 要求为null的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为{@code null}或空则默认为'true'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param likeOp 模糊匹配方式
	 * @return 当前对象
	 * @see #likeIf(String, String, String, LikeOp, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder likeIf(String[] testVars,VarTestType testType, String field,LikeOp likeOp){
		return likeIf(renderVars(testVars, testType),null,field,likeOp, true);
	}
	/**
	 * 根据{@code testType}指定的类型测试{@code testVar} 指定的变量满足条件,则创建LIKE表达式<br>
	 * {@code field,testType}为{@code null}或空视则忽略,不生成表达式
	 * @param testVar 条件测试表达式变量名,为{@code null}或空则默认为{@code field}
	 * @param testType 变量测试类型
	 * @param testOp 条件测试操作符
	 * @param testValue 变量条件测试的目标值 
	 * @param testQuote 为{@code true}生成表达式对{@code testValue} 以字符串对头尾增加单引号,{@code refValue}为{@code true}时忽略
	 * @param testRefValue 为{@code true}生成表达式对{@code testValue} 视为变量名
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 创建等价表达式的字段名
	 * @param likeOp 模糊匹配方式
	 * @param refValue 为{@code true}生成表达式对{@code field} 视为变量名,否则视为常量
	 * @return 当前对象
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder likeIf(String testVar,VarTestType testType,CompareOp testOp, Object testValue,boolean testQuote,boolean testRefValue, 
			String left,String field, LikeOp likeOp, boolean refValue){
		String test = buildTestVarExp(testVar, testType, testOp, testValue, testQuote, testRefValue, field);
		return likeIf(test,left,field,likeOp, refValue);
	}
	/**
	 * 创建算述比较表达式，如{@code  column_name > $<column_name>}<br>
	 * 当 {@code checkFieldEmpty} 为{@code true}对{@code field}指定的变量执行判断空检查，如果不为{@code null}或空则创建表达式，
	 * 当 {@code checkFieldEmpty} 为{@code false}对{@code field}指定的变量执行判断null检查，如果不为{@code null}则创建表达式，
	 * @param test 判断条件,条件为'true'则生成LIKE表达式,为{@code null}或空则默认为'true'
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param op 算述比较运算符
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @param refValue 为{@code true}生成表达式对{@code field} 视为变量名,否则视为常量
	 * @param checkFieldEmpty 是否对{@code field}指定的变量执行判断空检查,此参数对于类型为String的参数有影响<br>
     *                        <ul>
     *                        <li>{@code true} -- {@code field}指定的变量执行判断空检查</li>
     *                        <li>{@code false} -- 只需要判断是否为{@code null}</li>
     *                        <li>空                  -- 使用{@code quote}</li>
     *                        </ul>
	 * @return 当前对象
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder compare(String test,
			String left,String field,CompareOp op, boolean quote, 
			boolean refValue, Boolean checkFieldEmpty){
		if(!isNullOrEmpty(field) && null != op) {
			checkValidLeft(refValue,left);
			/**
			 * 非引用模式下，如果不要求加引号，则要求field不能为全空格([ \t\n\r\f\v])字符串否则抛出异常
			 * 因为这样生成的脚本肯定会因为有语法错误而报错
			 * */ 
			if(!refValue && !quote && field.replaceAll("\\s*","").isEmpty()) {
				throw new WhereHelperException("NOT EMPTY string required for field if refValue is false");
			}
			String checkEmpty;
			if(refValue) {
				checkEmpty = firstNonNull(checkFieldEmpty, quote)?"!isEmpty(${$<field>})":"isNonull(${$<field>})";
			}else {
				checkEmpty = "true";
			}
			conditionCodes.add(Tmpls.tmpls.get(TMPL_COMPARE)
					.replace(AND_OR, andor)
					.replace("$<CHECK_EMPTY>", checkEmpty)
					.replace("${$<field>}", (isNullOrEmpty(left) ||  refValue)?"${$<field>}":field)
					.replace("$<left>", column(left,field))
					.replace("$<field>", field)
	                .replace(TEST, isNullOrEmpty(test)?"true":test)
	                .replace("$<QUOTE>", String.valueOf(quote))
					.replace("$<COMPARE_OP>", op.op));
		}
		return this;
	}
	/**
	 * 创建算述比较表达式，如{@code  column_name > $<column_name>}<br>
	 * @param test 判断条件,条件为'true'则生成LIKE表达式,为{@code null}或空则默认为'true'
	 * @param testNullVars 要求为{@code null}的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为{@code null}或空则默认为'true'
	 * @param testNonullVars 要求不为{@code null}的变量名列表,['var1','var2'],等价于'null!=${var1} && null!=${var2}',为{@code null}或空则默认为'true'
	 * @param testEmptyVars 要求为{@code null}或空的变量名列表,['var1','var2'],等价于'isEmpty(${var1}) && isEmpty(${var2})',为{@code null}或空则默认为'true'
	 * @param testNoEmptyVars 要求不为{@code null}或空的变量名列表,['var1','var2'],等价于'!isEmpty(${var1}) && !isEmpty(${var2})',为{@code null}或空则默认为'true'
	 * @param testTrueVars 要求为{@code true}的变量名列表,['var1','var2'],等价于'isTrue(${var1)} && isTrue(${var2})',为空则默认为'true'
	 * @param testFalseVars 要求为{@code false}的变量名列表,['var1','var2'],等价于'isFalse(${var1}) && isFalse(${var2})',为空则默认为'true'
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param compareOp 算述比较运算符
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @param checkFieldEmpty 是否对{@code field}指定的变量执行判断空检查,此参数对于类型为String的参数有影响
	 * @return 当前对象
	 * @see #compare(String, String, String, CompareOp, boolean, boolean, Boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder compare(String test,
			String[] testNullVars,String[] testNonullVars,String[] testEmptyVars, String[] testNoEmptyVars, 
			String[] testTrueVars, String[] testFalseVars, String left, String field, CompareOp compareOp, boolean quote, Boolean checkFieldEmpty){
		return compare(buildTestExps(test, testNullVars, testNonullVars, testEmptyVars, testNoEmptyVars, testTrueVars, testFalseVars), 
				left, field, compareOp, quote, true, checkFieldEmpty);
	}
	/**
	 * 创建算述比较表达式，如{@code  column_name > $<column_name>}<br>
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param op 算述比较运算符
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @param refValue 为{@code true}生成表达式对{@code field} 视为变量名,否则视为常量
	 * @return 当前对象
	 * @see #compare(String, String, String, CompareOp, boolean, boolean, Boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder compare(String left, String field, CompareOp op, boolean quote, boolean refValue){
		return compare(null,left,field,op,quote,refValue, null);
	}
	/**
	 * 创建算述比较表达式，如{@code  column_name > $<column_name>}<br>
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param op 算述比较运算符
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @return 当前对象
	 * @see #compare(String, String, String, CompareOp, boolean, boolean, Boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder compare(String left, String field, CompareOp op, boolean quote){
		return compare(null,left,field,op,quote,true, null);
	}
	/**
	 * 创建算述比较表达式，如{@code  column_name > $<column_name>}<br>
	 * @param field 变量名,不为null或空，否则忽略
	 * @param op 算述比较运算符
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @return 当前对象
	 * @see #compare(String, String, String, CompareOp, boolean, boolean, Boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder compare(String field, CompareOp op, boolean quote){
		return compare(null,null,field,op,quote,true, null);
	}
		
	/**
	 * 如果{@code test} 定义的表达式为{@code true}} ,则创建算述比较表达式，如{@code  column_name > $<column_name>}<br>
	 * @param test 判断条件,条件为'true'则生成比较表达式,为{@code null}或空则不创建表达式
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param op 算述比较运算符
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @param refValue 为{@code true}生成表达式对{@code field} 视为变量名,否则视为常量
	 * @return 当前对象
	 * @see #compare(String, String, String, CompareOp, boolean, boolean, Boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder compareIf(String test,String left, String field, CompareOp op, boolean quote, boolean refValue){
		if(!isNullOrEmpty(test)) {
			return compare(test,left,field,op,quote,refValue, null);
		}
		return this;
	}
	/**
	 * 如果{@code test} 定义的表达式为{@code true}} ,则如果{@code test} 定义的表达式为{@code true}} ,则创建算述比较表达式，如{@code  column_name > $<column_name>}<br>
	 * @param test 判断条件,条件为'true'则生成LIKE表达式,为{@code null}或空则默认为'true'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param op 算述比较运算符
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @return 当前对象
	 * @see #compareIf(String, String, String, CompareOp, boolean, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder compareIf(String test,String field, CompareOp op, boolean quote){
		return compareIf(test,null,field,op,quote, true);
	}

	/**
	 * 根据{@code testType}指定的类型测试{@code testVars} 指定的变量所有变量都满足条件,则创建算述比较表达式，如{@code  column_name > $<column_name>}<br>
	 * {@code testVars,testType}为{@code null}或空视为{@code true},
	 * @param testVars 要求为null的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为{@code null}或空则默认为'true'
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param op 算述比较运算符
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @return 当前对象
	 * @see #compareIf(String, String, String, CompareOp, boolean, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder compareIf(String[] testVars,VarTestType testType, String left, String field, CompareOp op, boolean quote){
		return compareIf(renderVars(testVars, testType),left,field,op,quote, true);
	}
	/**
	 * 根据{@code testType}指定的类型测试{@code testVars} 指定的变量所有变量都满足条件,则创建算述比较表达式，如{@code  column_name > $<column_name>}<br>
	 * {@code testVars,testType}为{@code null}或空视为{@code true},
	 * @param testVars 要求为null的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为{@code null}或空则默认为'true'
	 * @param field 变量名,不为null或空，否则忽略
	 * @param op 算述比较运算符
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @return 当前对象
	 * @see #compareIf(String, String, String, CompareOp, boolean, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder compareIf(String[] testVars,VarTestType testType, String field, CompareOp op, boolean quote){
		return compareIf(renderVars(testVars, testType),null,field,op,quote, true);
	}
	/**
	 * 根据{@code testType}指定的类型测试{@code testVar} 指定的变量满足条件,则创建算述比较表达式，
	 * 如{@code  column_name > $(column_name)}<br>
	 * {@code field,testType}为{@code null}或空视则忽略,不生成表达式
	 * @param testVar 条件测试表达式变量名,为{@code null}或空则默认为{@code field}
	 * @param testType 变量测试类型
	 * @param testOp 条件测试操作符
	 * @param testValue 变量条件测试的目标值 
	 * @param testQuote 为{@code true}生成表达式对{@code testValue} 以字符串对头尾增加单引号,{@code refValue}为{@code true}时忽略
	 * @param testRefValue 为{@code true}生成表达式对{@code testValue} 视为变量名
	 * @param left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例left为'dcc.',field为'name',则左侧表达式为'dcc.name'
	 * @param field 创建等价表达式的字段名
	 * @param op 算述比较运算符
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @param refValue 为{@code true}生成表达式对{@code field} 视为变量名,否则视为常量
	 * @return 当前对象
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder compareIf(String testVar,VarTestType testType,CompareOp testOp, Object testValue,boolean testQuote,boolean testRefValue, 
			String left, String field, CompareOp op, boolean quote,boolean refValue){
		String test = buildTestVarExp(testVar, testType, testOp, testValue, testQuote, testRefValue, field);
		return compareIf(test,left,field,op, quote, refValue);
	}
	/**
	 * 创建数值范围算述比较表达式，如{@code  column_name > $(column_name_min) && column_name <= $(column_name_max)}<br>
	 * 当 {@code checkFieldEmpty} 为{@code true}对{@code field}指定的变量执行判断空检查，如果不为{@code null}或空则创建表达式，
	 * 当 {@code checkFieldEmpty} 为{@code false}对{@code field}指定的变量执行判断null检查，如果不为{@code null}则创建表达式，
	 * @param test 判断条件,条件为'true'则生成LIKE表达式,为{@code null}或空则默认为'true'
	 * @param field 字段名,不为null或空，否则忽略
	 * @param lowerVar 左侧范围(较小值)变量名,不为null或空，否则忽略
	 * @param lowerSuffix 左侧范围(较小值)变量名后缀
	 * @param lowerRefValue 为{@code true}生成SQL表达式对{@code lowerVar}视为变量名,否则视为常量
	 * @param upperVar 右侧范围(较大值) 变量名,不为null或空，否则忽略
	 * @param upperSuffix 右侧范围(较大值) 变量名后缀
	 * @param upperRefValue 为{@code true}生成SQL表达式对{@code upperVar} 视为变量名,否则视为常量
	 * @param rangeType 范围类型
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @param checkFieldEmpty 是否对{@code field}指定的变量执行判断空检查,此参数对于类型为String的参数有影响<br>
     *                        <ul>
     *                        <li>{@code true} -- {@code field}指定的变量执行判断空检查</li>
     *                        <li>{@code false} -- 只需要判断是否为{@code null}</li>
     *                        <li>空                  -- 使用{@code quote}</li>
     *                        </ul>
	 * @return 当前对象
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder range(String test,
			String field,String lowerVar,String lowerSuffix, boolean lowerRefValue, 
			String upperVar, String upperSuffix, boolean upperRefValue, RangeType rangeType, boolean quote, Boolean checkFieldEmpty){
		if(!isNullOrEmpty(field)) {
				rangeType = firstNonNull(rangeType, RangeType.CLOSEOPEN);
				compare(test, field,rangeVar(field,lowerVar,lowerSuffix),rangeType.lower,quote, lowerRefValue, checkFieldEmpty);
				compare(test, field,rangeVar(field,upperVar,upperSuffix),rangeType.upper,quote, upperRefValue, checkFieldEmpty);
		}
		return this;
	}
	/**
	 * 创建数值范围算述比较表达式，如{@code  column_name > $(column_name_min) && column_name <= $(column_name_max)}<br>
	 * @param test 判断条件,条件为'true'则生成LIKE表达式,为{@code null}或空则默认为'true'
	 * @param testNullVars 要求为{@code null}的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为{@code null}或空则默认为'true'
	 * @param testNonullVars 要求不为{@code null}的变量名列表,['var1','var2'],等价于'null!=${var1} && null!=${var2}',为{@code null}或空则默认为'true'
	 * @param testEmptyVars 要求为{@code null}或空的变量名列表,['var1','var2'],等价于'isEmpty(${var1}) && isEmpty(${var2})',为{@code null}或空则默认为'true'
	 * @param testNoEmptyVars 要求不为{@code null}或空的变量名列表,['var1','var2'],等价于'!isEmpty(${var1}) && !isEmpty(${var2})',为{@code null}或空则默认为'true'
	 * @param testTrueVars 要求为{@code true}的变量名列表,['var1','var2'],等价于'isTrue(${var1)} && isTrue(${var2})',为空则默认为'true'
	 * @param testFalseVars 要求为{@code false}的变量名列表,['var1','var2'],等价于'isFalse(${var1}) && isFalse(${var2})',为空则默认为'true'
	 * @param field 字段名,不为null或空，否则忽略
	 * @param lowerVar 左侧范围(较小值)变量名,不为null或空，否则忽略
	 * @param lowerSuffix 左侧范围(较小值)变量名后缀
	 * @param lowerRefValue 为{@code true}生成SQL表达式对{@code lowerVar}视为变量名,否则视为常量
	 * @param upperVar 右侧范围(较大值) 变量名,不为null或空，否则忽略
	 * @param upperSuffix 右侧范围(较大值) 变量名后缀
	 * @param upperRefValue 为{@code true}生成SQL表达式对{@code upperVar} 视为变量名,否则视为常量
	 * @param rangeType 范围类型
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @param checkFieldEmpty 是否对{@code field}指定的变量执行判断空检查,此参数对于类型为String的参数有影响
	 * @return 当前对象
	 * @see #range(String, String, String, String, boolean, String, String, boolean, RangeType, boolean, Boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder range(String test,
			String[] testNullVars,String[] testNonullVars,String[] testEmptyVars, String[] testNoEmptyVars, 
			String[] testTrueVars, String[] testFalseVars, String field, 
			String lowerVar,	String lowerSuffix, boolean lowerRefValue,
			String upperVar, String upperSuffix, boolean upperRefValue, 
			RangeType rangeType, boolean quote, Boolean checkFieldEmpty){
		return range(buildTestExps(test, testNullVars, testNonullVars, testEmptyVars, testNoEmptyVars, testTrueVars, testFalseVars), 
				field, lowerVar, lowerSuffix, lowerRefValue, upperVar, upperSuffix, upperRefValue, rangeType, quote, checkFieldEmpty);
	}

	/**
	 * 创建数值范围算述比较表达式，如{@code  column_name > $(column_name_min) && column_name <= $(column_name_max)}<br>
	 * @param field 字段名,不为null或空，否则忽略
	 * @param lowerVar 左侧范围(较小值)变量名,不为null或空，否则忽略
	 * @param lowerSuffix 左侧范围(较小值)变量名后缀
	 * @param lowerRefValue 为{@code true}生成SQL表达式对{@code lowerVar}视为变量名,否则视为常量
	 * @param upperVar 右侧范围(较大值) 变量名,不为null或空，否则忽略
	 * @param upperSuffix 右侧范围(较大值) 变量名后缀
	 * @param upperRefValue 为{@code true}生成SQL表达式对{@code upperVar} 视为变量名,否则视为常量
	 * @param rangeType 范围类型,为{@code null}则视为默认值: {@link RangeType#OPENCLOSE} 
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @return 当前对象
	 * @see #range(String, String, String, String, boolean, String, String, boolean, RangeType, boolean, Boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder range(String field, String lowerVar,String lowerSuffix, boolean lowerRefValue,String upperVar, String upperSuffix, 
			boolean upperRefValue, RangeType rangeType, boolean quote){
		return range(null,field,lowerVar,lowerSuffix,lowerRefValue,upperVar,upperSuffix,upperRefValue,rangeType, quote, null);
	}
	/**
	 * 创建数值范围算述比较表达式，如{@code  column_name > $(column_name_min) && column_name <= $(column_name_max)}<br>
	 * @param field 字段名,不为null或空，否则忽略
	 * @param lowerVar 左侧范围(较小值)变量名,不为null或空，否则忽略
	 * @param upperVar 右侧范围(较大值) 变量名,不为null或空，否则忽略
	 * @param rangeType 范围类型,为{@code null}则视为默认值: {@link RangeType#OPENCLOSE} 
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @return 当前对象
	 * @see #range(String, String, String, String, boolean, String, String, boolean, RangeType, boolean, Boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder range(String field, String lowerVar, String upperVar, RangeType rangeType, 
			boolean quote){
		return range(null,field,lowerVar,"_min",true,upperVar,"_max",true,rangeType, quote, null);
	}
	/**
	 * 创建数值范围算述比较表达式，如{@code  column_name > $(column_name_min) && column_name <= $(column_name_max)}<br>
	 * @param field 字段名,不为null或空，否则忽略
	 * @param rangeType 范围类型,为{@code null}则视为默认值: {@link RangeType#OPENCLOSE} 
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @return 当前对象
	 * @see #range(String, String, String, String, boolean, String, String, boolean, RangeType, boolean, Boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder range(String field, RangeType rangeType, 
			boolean quote){
		return range(null,field,null,"_min",true,null,"_max",true,rangeType, quote, null);
	}
	/**
	 * 创建数值范围算述比较表达式，如{@code  column_name > $(column_name_min) && column_name <= $(column_name_max)}<br>
	 *  范围类型为{@link RangeType#OPENCLOSE} 
	 * @param field 字段名,不为null或空，否则忽略
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @return 当前对象
	 * @see #range(String, String, String, String, boolean, String, String, boolean, RangeType, boolean, Boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder range(String field, 	boolean quote){
		return range(null,field,null,"_min",true,null,"_max",true,RangeType.OPENCLOSE, quote, null);
	}
	/**
	 * 如果{@code test} 定义的表达式为{@code true}} ,则创建数值范围算述比较表达式，如{@code  column_name > $(lower_value)> && column_name <= $(upper_value)}<br>
	 * @param test 判断条件,条件为'true'则生成LIKE表达式,为{@code null}或空则不创建表达式
	 * @param field 字段名,不为null或空，否则忽略
	 * @param lowerVar 左侧范围(较小值)变量名,不为null或空，否则忽略
	 * @param lowerSuffix 左侧范围(较小值)变量名后缀
	 * @param lowerRefValue 为{@code true}生成SQL表达式对{@code lowerVar}视为变量名,否则视为常量
	 * @param upperVar 右侧范围(较大值) 变量名,不为null或空，否则忽略
	 * @param upperSuffix 右侧范围(较大值) 变量名后缀
	 * @param upperRefValue 为{@code true}生成SQL表达式对{@code upperVar} 视为变量名,否则视为常量
	 * @param rangeType 范围类型,为{@code null}则视为默认值: {@link RangeType#OPENCLOSE} 
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @return 当前对象
	 * @see #range(String, String, String, String, boolean, String, String, boolean, RangeType, boolean, Boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder rangeIf(String test,
			String field,String lowerVar,String lowerSuffix, boolean lowerRefValue,String upperVar, String upperSuffix, 
			boolean upperRefValue, RangeType rangeType, boolean quote){
		if(!isNullOrEmpty(test)) {
			return range(test,field,lowerVar,lowerSuffix,lowerRefValue,upperVar,upperSuffix,upperRefValue,rangeType, quote, null);
		}
		return this;
	}
	/**
	 * 如果{@code test} 定义的表达式为{@code true}} ,则创建数值范围算述比较表达式，如{@code  column_name > $(column_name_min) && column_name <= $(column_name_max)}<br>
	 * @param test 判断条件,条件为'true'则生成LIKE表达式,为{@code null}或空则不创建表达式
	 * @param field 字段名,不为null或空，否则忽略
	 * @param lowerVar 左侧范围(较小值)变量名,不为null或空，否则忽略
	 * @param upperVar 右侧范围(较大值) 变量名,不为null或空，否则忽略
	 * @param rangeType 范围类型,为{@code null}则视为默认值: {@link RangeType#OPENCLOSE} 
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @return 当前对象
	 * @see #rangeIf(String, String, String, String, boolean, String, String, boolean, RangeType, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder rangeIf(String test,	String field,String lowerVar,String upperVar, RangeType rangeType, boolean quote){
		return rangeIf(test,field,lowerVar,"_min",true,upperVar,"_max",true,rangeType, quote);
	}
	/**
	 * 如果{@code test} 定义的表达式为{@code true}} ,则创建数值范围算述比较表达式，如{@code  column_name > $(column_name_min) && column_name <= $(column_name_max)}<br>
	 * @param test 判断条件,条件为'true'则生成LIKE表达式,为{@code null}或空则不创建表达式
	 * @param field 字段名,不为null或空，否则忽略
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @return 当前对象
	 * @see #rangeIf(String, String, String, String, boolean, String, String, boolean, RangeType, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder rangeIf(String test,	String field, boolean quote){
		return rangeIf(test,field,null,"_min",true,null,"_max",true,RangeType.OPENCLOSE, quote);
	}
	/**
	 * 根据{@code testType}指定的类型测试{@code testVars} 指定的变量所有变量都满足条件,则创建数值范围算述比较表达式，如{@code  column_name > $(column_name_min) && column_name <= $(column_name_max)}<br>
	 * {@code testVars,testType}为{@code null}或空视为{@code true},
	 * @param testVars 要求为{@code null}的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为{@code null}或空则默认为'true'
	 * @param field 字段名,不为null或空，否则忽略
	 * @param lowerVar 左侧范围(较小值)变量名,不为null或空，否则忽略
	 * @param lowerSuffix 左侧范围(较小值)变量名后缀
	 * @param lowerRefValue 为{@code true}生成SQL表达式对{@code lowerVar}视为变量名,否则视为常量
	 * @param upperVar 右侧范围(较大值) 变量名,不为null或空，否则忽略
	 * @param upperSuffix 右侧范围(较大值) 变量名后缀
	 * @param upperRefValue 为{@code true}生成SQL表达式对{@code upperVar} 视为变量名,否则视为常量
	 * @param rangeType 范围类型,为{@code null}则视为默认值: {@link RangeType#OPENCLOSE} 
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @return 当前对象
	 * @see #rangeIf(String, String, String, String, boolean, String, String, boolean, RangeType, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder rangeIf(String[] testVars,VarTestType testType,String field,
			String lowerVar,String lowerSuffix, boolean lowerRefValue,
			String upperVar, String upperSuffix, boolean upperRefValue, 
			RangeType rangeType, boolean quote){
		return rangeIf(renderVars(testVars, testType),field,lowerVar,lowerSuffix,lowerRefValue,upperVar,upperSuffix,upperRefValue,rangeType, quote);
	}
	/**
	 * 根据{@code testType}指定的类型测试{@code testVars} 指定的变量所有变量都满足条件,则创建数值范围算述比较表达式，如{@code  column_name > $(column_name_min) && column_name <= $(column_name_max)}<br>
	 * {@code testVars,testType}为{@code null}或空视为{@code true},
	 * @param testNullVars 要求为{@code null}的变量名列表,['var1','var2'],等价于'null==${var1} && null==${var2}',为{@code null}或空则默认为'true'
	 * @param field 字段名,不为null或空，否则忽略
	 * @param lowerVar 左侧范围(较小值)变量名,不为null或空，否则忽略
	 * @param upperVar 右侧范围(较大值) 变量名,不为null或空，否则忽略
	 * @param rangeType 范围类型,为{@code null}则视为默认值: {@link RangeType#OPENCLOSE} 
	 * @param quote 为{@code true}生成表达式对数值以字符串对头尾增加单引号
	 * @return 当前对象
	 * @see #rangeIf(String, String, String, String, boolean, String, String, boolean, RangeType, boolean)
	 * @since 3.25.0
	 */
	public BeanShellWhereBuilder rangeIf(String[] testNullVars,VarTestType testType,	String field,
			String lowerVar, String upperVar, RangeType rangeType, boolean quote){
		return range(renderVars(testNullVars, testType),field,lowerVar,"_min",true,upperVar,"_max",true,rangeType, quote, null);
	}
	/**
	 * 指定SELECT .... FROM 语句,如果不指定，则只生成 WHERE ....部分语句
	 * @param selectFrom select 语句(不含 WHERE部分),为{@code null}忽略
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder selectFrom(String selectFrom) {
		if(!isNullOrEmpty(selectFrom)) {
			this.selectFrom = selectFrom;
		}
		return this;
	}
	/**
	 * 指定ORDER BY 的字段名
	 * @param columnName order by 字段名
	 * @param desc 排序方式,为{@code true}降序
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder orderBy(String columnName,boolean desc) {
		columnName = nullToEmpty(columnName).trim();
		if(!isNullOrEmpty(columnName)) {			
			checkArgument(columnName.matches("('\\w+'|\\w+)"));
			orderByColumns.add(columnName +(desc?" DESC ": ""));
		}
		return this;
	}
	/**
	 * 指定ORDER BY 的字段名,格式要求 ${字段名}[ DESC|ASC]
	 * @param columnName order by 字段名,为{@code null}或空忽略
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder orderBy(String columnName) {
		if(!isNullOrEmpty(columnName)){
			orderByColumns.add(validOrderBy(columnName));
		}
		return this;
	}
	/**
	 * 指定ORDER BY 的字段变量名
	 * @param varName order by 字段字段名,为{@code null}或空忽略
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder orderByVar(String varName) {
		if(!isNullOrEmpty(varName)){
			varName = varName.trim();
			// 必须是以字母开头的只包含数字字母下划线的字符串
			checkArgument(varName.matches("^[_a-zA-Z]\\w*(\\.\\w+)?$"),"INVALID variable name [%s]",varName);
			this.orderByVarname = varName; 
		}
		return this;
	}

	/**
	 * 指定GROUP BY 的字段名
	 * @param columnNames group by 字段名列表,为{@code null}忽略
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder groupBy(String ...columnNames) {
		if(null != columnNames){
			Iterable<String> normalized = Iterables.transform(Arrays.asList(columnNames), getFormatJsonFieldFunction());
			Iterables.addAll(groupByColumns, 
					Iterables.filter(normalized, s->!isNullOrEmpty(s)));
		}
		return this;
	}
	/**
	 * 指定GROUP BY 的字段变量名
	 * @param varName group by 字段变量名,为{@code null}或空忽略
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder groupByVar(String varName) {
		if(!isNullOrEmpty(varName)){
			varName = varName.trim();
			// 必须是以字母开头的只包含数字字母下划线的字符串
			checkArgument(varName.matches("$[[:alpha:]]\\w?"));
			this.groupByVarname = varName; 
		}
		return this;
	}
	/**
	 * 增加import类型语句，每一个元素为一行导入语句，为{@code null}或空忽略。
	 * 如: {@code import xxx..xxx.ClassA;} 或只提供导入类全名 {@code xxx..xxx.ClassA}
	 * @param imports
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder imports(String ...imports){
		if(null != imports){
			return withImports(Arrays.asList(imports));
		}
		return this;
	}
	/**
	 * 增加import类型语句，每一个元素为一行导入语句，为{@code null}或空忽略。
	 * 如: {@code import xxx..xxx.ClassA;}或只提供导入类全名 {@code xxx..xxx.ClassA}
	 * @param imports
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder withImports(Iterable<String> imports){
		if(null != imports){
			Iterable<String> trans = Iterables.transform(imports, imp->{
				imp = nullToEmpty(imp).trim();
				if(!imp.isEmpty()){
					if(!imp.startsWith("import")){
						imp = "import " + imp;
					}
					if(!imp.endsWith(";")){
						imp = imp + ";";
					}
					imp = imp.replace('$', '.');
				}
				return imp;
			});
			Iterables.addAll(importLines,trans);
		}
		return this;
	}
	/**
	 * 从注解中创建表达式
	 * @param annots
	 * @return 当前对象
	 */
	public BeanShellWhereBuilder from(Annotation[] annots){
		if(null != annots){
			for(Annotation a:annots){
				if(a.annotationType() == EnableWhereHelper.class){
					EnableWhereHelper enableWhereHelper = (EnableWhereHelper)a;
					selectFrom = enableWhereHelper.value();
					debuglog = enableWhereHelper.debuglog();
					andor = validLogicOperator(enableWhereHelper.logicOperator());
					targetClass  = enableWhereHelper.targetClass();
					buildVarTypes(enableWhereHelper);
				}else if(a.annotationType() == Equal.class ){
					Equal eq = (Equal)a;
					equal(eq.left(),eq.value(),eq.not(), eq.orNull()?false:eq.notCheckEmpty(), eq.orNull());
				}else if(a.annotationType() == BitTest.class ){
					BitTest eq = (BitTest)a;
					bitTest(eq.left(),eq.value(),eq.bitOr(), eq.orNull()?false:eq.notCheckEmpty(), eq.aggFun());
				}else if(a.annotationType() == EqualIf.class ){
					EqualIf eq = (EqualIf)a;
					String testVarExp = buildTestVarExp(eq.testVar(), eq.testType(), eq.testOp(), 
							eq.testValue(), eq.testQuote(),eq.testRefValue(),eq.field());
					String testexps = buildTestExps(eq.test(), 
							eq.testNullVars(),eq.testNonullVars(),
							eq.testEmptyVars(),eq.testNoEmptyVars(), 
							eq.testTrueVars(), eq.testFalseVars());
					equalIf(reduceExps(testexps,testVarExp),eq.left(),eq.field(), eq.not(), eq.notCheckEmpty());
				}else if(a.annotationType() == Expression.class ){
					Expression exp = (Expression)a;
					exp(exp.value());
				}else if(a.annotationType() == Like.class ){
					Like like = (Like)a;
					String testVarExp = buildTestVarExp(like.testVar(), like.testType(), like.testOp(), 
							like.testValue(), like.testQuote(),like.testRefValue(),like.value());
					String testexps = buildTestExps(like.test(), 
							like.testNullVars(),like.testNonullVars(),
							like.testEmptyVars(),like.testNoEmptyVars(), 
							like.testTrueVars(), like.testFalseVars());
					like(reduceExps(testexps,testVarExp),like.left(),like.value(),like.op(), like.refValue());
				}else if(a.annotationType() == Compare.class ){
					Compare cmp = (Compare)a;
					String testVarExp = buildTestVarExp(cmp.testVar(), cmp.testType(), cmp.testOp(), 
							cmp.testValue(), cmp.testQuote(),cmp.testRefValue(),cmp.value());
					String testexps = buildTestExps(cmp.test(), 
							cmp.testNullVars(),cmp.testNonullVars(),
							cmp.testEmptyVars(),cmp.testNoEmptyVars(), 
							cmp.testTrueVars(), cmp.testFalseVars());
					compare(reduceExps(testexps,testVarExp),
							cmp.left(),cmp.value(),cmp.op(),cmp.quote(),
							cmp.refValue(), 
							/** 为空使用 quote */
							cmp.checkFieldEmpty().length==0 ? cmp.quote() : cmp.checkFieldEmpty()[0]);
				}else if(a.annotationType() == Range.class ){
					Range range = (Range)a;
					String testVarExp = buildTestVarExp(range.testVar(), range.testType(), range.testOp(), 
							range.testValue(), range.quote(),range.testRefValue(),range.testVar());
					String testexps = buildTestExps(range.test(), 
							range.testNullVars(),range.testNonullVars(),
							range.testEmptyVars(),range.testNoEmptyVars(), 
							range.testTrueVars(), range.testFalseVars());
					range(reduceExps(testexps,testVarExp),
							range.field(),
							range.lowerVar(), range.lowerSuffix(),range.lowerRefValue(),
							range.upperVar(), range.upperSuffix(),range.upperRefValue(), 
							range.rangeType(), range.quote(), /** 为空使用 quote */
							range.checkFieldEmpty().length==0 ? range.quote() : range.checkFieldEmpty()[0]);
				}else if(a.annotationType() == IfElse.class){
					IfElse ifelse = (IfElse)a;
					String testVarExp = buildTestVarExp(ifelse.testVar(), ifelse.testType(), ifelse.testOp(), 
							ifelse.testValue(), ifelse.testQuote(),ifelse.testRefValue(),ifelse.testVar());
					String testexps = buildTestExps(ifelse.test(), 
							ifelse.testNullVars(),ifelse.testNonullVars(),
							ifelse.testEmptyVars(),ifelse.testNoEmptyVars(), 
							ifelse.testTrueVars(), ifelse.testFalseVars());
					ifelse(reduceExps(testexps,testVarExp), ifelse.doStatement(), ifelse.elseStatement());
				}else if (a.annotationType() == OrderBy.class) {
					OrderBy orderBy = (OrderBy)a;
					String[] orderBys = orderBy.value();
					for(String o: orderBys){
						orderBy(o);
					}
					orderByVar(orderBy.orderByVarname());
				} else if (a.annotationType() == GroupBy.class) {
					groupBy(((GroupBy)a).value());
				} else {
					try {
						Method method = a.annotationType().getMethod("value");
						Class<?> returnType = method.getReturnType();
						if(returnType.isArray() && Annotation.class.isAssignableFrom(returnType.getComponentType()) ){
							// 递归
							from((Annotation[])method.invoke(a));
						}
					} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
					}
				}
			}
		}
		return this;
	}
	/**
	 * 根据指定的条件生成BeanShell脚本
	 * @return BeanShell脚本字符串
	 */
	String buildScript() {
		//checkState(!conditionCodes.isEmpty(),"must define condition statement");
		conditionCodes.add(Tmpls.tmpls.get(TMPL_GROUP_BY)
				.replace("${"+DEFAULT_GROUP_BY_VAR+"}", "${"+groupByVarname+"}"));
		conditionCodes.add(Tmpls.tmpls.get(TMPL_ORDER_BY)
				.replace("${"+DEFAULT_ORDER_BY_VAR+"}", "${"+orderByVarname+"}"));
		if(pagequery){
			if(DT_MYSQL.equals(sqltype)){
				conditionCodes.add(Tmpls.tmpls.get(TMPL_LIMIT));
			}
		}
		StringBuffer buffer = new StringBuffer();
		if(!importLines.isEmpty()){
			buffer.append(Joiner.on("\n").join(importLines));
		}
		if(!selectFrom.isEmpty()) {
			buffer.append(String.format("where_buffer.append(\"%s \");\n",selectFrom));
		}
		String script=buffer.append(Tmpls.tmpls.get(TMPL_BEFORE_COND))
				.append(extractReferenceVariables(Joiner.on("\n").join(conditionCodes)))
				.append(Tmpls.tmpls.get(TMPL_AFTER_COND)).toString();
		log(debuglog,"\n"+renderLine(script));
		log(debuglog,"referenceVariables: {}",Iterables.toString(referenceVariables));
		
		return script;
	}
	/**
	 * 将字符串中的${varname}格式的变量引用名从字符串中摘出参与运算,
	 * 并生成引用变量名集合保存到{@link #referenceVariables} 
	 * @param input
	 * @return 引用变量名集合
	 */
	private String extractReferenceVariables(String input){
		this.referenceVariables = Sets.newHashSet();
		if(!isNullOrEmpty(input)){
			Pattern pattern = Pattern.compile("\\$\\{(\\w+)\\}");
			Matcher matcher = pattern.matcher(input);
			 while (matcher.find()) {
				 referenceVariables.add(matcher.group(1));
			 }
			
			 return replaceVar(input);
		}
		return input;
	}
	
	/**
	 * 通过正则表达式匹配将字符串中的${varname}格式的变量引用名从字符串中摘出参与运算,
	 * @param input
	 * @return 替换后的字符串
	 */
	private String replaceVar(String input){
		/** 
		 * 支持 (?<!pattern) 负向后行断言的正则表达式，用于提取一个双引号开头和结尾的正则表达式
		 * 参见 https://www.runoob.com/w3cnote/reg-lookahead-lookbehind.html 
		 */
		Pattern p= Pattern.compile("(?<!\\\\)\".*?(?<!\\\\)\"");
		Matcher m = p.matcher(input); 
		StringBuffer sb = new StringBuffer();
		while(m.find()){
			String str = m.group(0)
					.replaceAll("\\$\\{(\\w+)\\}", "\"+$1+\"");
			/**
			 * Matcher.quoteReplacement 替换字符串的$符号，避免抛出异常
			 * 参见 https://blog.csdn.net/10km/article/details/131452599
			 */
			m.appendReplacement(sb, Matcher.quoteReplacement(str));
		}
		m.appendTail(sb);
		return sb.toString().replaceAll("\\$\\{(\\w+)\\}", "$1");
	}
	/**
	 * 从{@link EnableWhereHelper}的{@link EnableWhereHelper#varTypeKeys()}和{@link EnableWhereHelper#varTypeValues()}读取数据
	 * 生成字段名对应的类型映射{@link #varTypes}
	 * @param annot
	 */
	private void buildVarTypes(EnableWhereHelper annot){
		String[] varnames = annot.varTypeKeys();
		Class<?>[] vartypes = annot.varTypeValues();
		/** 数组长度必须一样 */
		checkArgument(varnames.length == vartypes.length,
				"INVALID variable type defined by EnableWhereHelper,array length of varTypeKeys must equal with varTypeValues");
		this.varTypes = Maps.newHashMap();
		for(int i=0;i<varnames.length;++i){
			checkArgument(!isNullOrEmpty(varnames[i]),"varname must not be empty");
			varTypes.put(varnames[i], vartypes[i]);
		}
	}
	/**
	 * 根据指定的条件生成{@link WhereHelper}实例
	 * @return WhereHelper 实例
	 */
	public WhereHelper build() {
		return new WhereHelper(this);
	}
	
	private static String  buildTestVarExp(String testVar,VarTestType testType,CompareOp testOp, Object testValue,boolean testQuote,boolean testRefValue, 
			String field){
		if(!isNullOrEmpty(field) && null != testType) {
			/** 2或3个操作数时要求 testValue不能为空 */
			if(testType.opcount > 1 && isEmpty(testValue)) {
				return "";
			}
			/** 3个操作数时要求 testOp不能为null */
			if(testType.opcount > 2 && (null == testOp)) {
				return "";
			}
			if(isNullOrEmpty(testVar)) {
				testVar = field;
			}
			return testType.render(testVar, testOp, testValue, testQuote,testRefValue);
		}
		return "";
	}

	/**
	 * 为输入的字符串每一行前端加行号
	 * @param input
	 */
	static String renderLine(String input) {
		if(!isNullOrEmpty(input)) {
			Pattern p1= Pattern.compile("^(.*)",Pattern.MULTILINE);
			Matcher m1 = p1.matcher(input); 
			StringBuffer sb = new StringBuffer();
			int line = 0;
			while(m1.find()){
				m1.appendReplacement(sb, String.format("%03d:$1",++line));
			}
			m1.appendTail(sb);
			return sb.toString();
		}
		return input;
	}
	/**
	 * 计算范围表达式的左右侧范围变量名<br>
	 * <table border="1">
	 * <tr><th align=left>var值</th><th align=left>suffix值</th><th align=left>field值</th><th align=left>返回值</th></tr>
	 * <tr><td>非空</td><td></td><td></td><td>var</td></tr>
	 * <tr><td>空</td><td>非空</td><td>非空</td><td>field+suffix</td></tr>
	 * <tr><td>空</td><td>空</td><td></td><td>null</td></tr>
	 * </table>
	 * @param field 字段名
	 * @param var   范围变量名
	 * @param suffix 范围变量名后缀
	 */
	private static String rangeVar(String field, String var,String suffix) {
		if(!isEmpty(var)) {
			return var;
		}
		if(!isNullOrEmpty(suffix) && !isNullOrEmpty(field)) {
			return field + suffix;
		}
		return null;
	}

	private static String renderVars(String[] testVars,VarTestType testType) {
		String truestr = String.valueOf(true);
		if(!isEmpty(testVars) && null != testType) {
			String defOp = " && ";
			String first = firstNonNull(testVars[0], defOp).trim() ;
			String rx = "^(&&|\\|\\|)$";
			String combinOp = first.matches(rx)? " "+ first +" ": defOp;
			return Arrays.asList(testVars)
					.stream().filter(s->!isNullOrEmpty(s)&& !s.trim().matches(rx)).map(testType::render).reduce((l,r)->l + combinOp + r).orElse(truestr);
		}
		return truestr;
	}
	static String buildTestExps(String test,
			String[] testNullVars,String[] testNonullVars, 
			String[] testEmptyVars, String[] testNoEmptyVars, 
			String[] testTrueVars, String[] testFalseVars){
		String truestr = String.valueOf(true);
		String nullexp = renderVars(testNullVars,VarTestType.NULL);
		String nonullexp = renderVars(testNonullVars,VarTestType.NONULL);
		String emptyexp = renderVars(testEmptyVars,VarTestType.EMPTY);
		String noemptyexp = renderVars(testNoEmptyVars,VarTestType.NOEMPTY);
		String trueexp = renderVars(testTrueVars,VarTestType.TRUE);
		String falseexp = renderVars(testFalseVars,VarTestType.FALSE);
		return Arrays.asList(isNullOrEmpty(test)? truestr:test,nullexp,nonullexp,emptyexp,noemptyexp,trueexp,falseexp)
			.stream()
			.filter(s->!truestr.equals(s))
			.reduce((l,r)->"("+l+") && ("+r+")").orElse(truestr);
	}
	private static String reduceExps(String... exps){
		return isEmpty(exps)? "":Arrays.asList(exps)
				.stream()
				.filter(s->!isNullOrEmpty(s))
				.reduce((l,r)->"("+l+") && ("+r+")").orElse("");
	}

	/**
	 * 根据输入的值计算表达式左边的字段名<br>
	 * left 为'.'结尾的字符串，则left被视为表名前缀，其左侧表达式值拼接会field，示例:left为'dcc.',field为'name',则返回的左侧表达式为'dcc.name'
	 * @param left 输入的表达式左侧字段名
	 * @param field 字段/变量名
	 */
	private static String column(String left,String field) {
		String _left = left;
		if(isNullOrEmpty(_left)) {
			_left = field;
		}else {
			if(_left.endsWith(".")) {
				_left += field;
			}else {
				if (_left.matches(".+->>?$")) {
					_left += field;
				}
				_left = getFormatJsonFieldFunction().apply(_left);
			} 
		}
		return _left;
	}
	/**
	 * 检查 输入的{@code left}是否有效无效则抛出异常 <br>
	 * {@code refValue}为{@code true}时 left 为{@code null}或空或 为'.'结尾的字符串，则抛出异常
	 * @param refValue 字段/变量名是否为引用
	 * @param left 输入的表达式左侧字段名
	 * @return always left
	 */
	private static String checkValidLeft(boolean refValue,String left) {
		if(!refValue && (isNullOrEmpty(left) ||left.endsWith("."))) {
			throw new WhereHelperException("INVALID left: " + String.valueOf(left)+" ,not null,not empty,not end with . required");
		}
		return left;
	}
	/**
	 * 适用于MYSQL的JSON字符表达格式化方法
	 */
	static final Function<String, String> FMT_JSON_FIELD_MYSQL = new Function<String, String>(){

		@Override
		public String apply(String input) {
			input = nullToEmpty(input).trim();
			Matcher matcher = Pattern.compile("(\\w+)->>?(\\$\\.)?(\\w+)|'(\\w+)->>?(\\$\\.)?(\\w+)'").matcher(input);
			StringBuffer buffer = new StringBuffer();
			while (matcher.find()) {
				if(!isNullOrEmpty(matcher.group(1))) {
					matcher.appendReplacement(buffer, "$1->>'\\$.$3'");
				}else {
					matcher.appendReplacement(buffer, "$4->>'\\$.$6'");	
				}
			}
			matcher.appendTail(buffer);
			return buffer.toString();
		}};
	/**
	 * @return JSON字符表达格式化方法
	 * @since 3.28.0
	 */
	static Function<String, String> getFormatJsonFieldFunction(){
		return FMT_JSON_FIELD_MYSQL;
	}
	/**
	 * 检查ORDER BY 字段的合法性,不合法则抛出异常
	 * @param input
	 * @return input always
	 */
	private static String validOrderBy(String input){
		input = getFormatJsonFieldFunction().apply(input);
		Matcher matcher = Pattern.compile("((^|,)\\s*(\\w+\\.)?\\w+(->>?'(\\$\\.)?\\w+')?(?: +(ASC|DESC))?)*",
				Pattern.CASE_INSENSITIVE).matcher(input);
		checkArgument(!isNullOrEmpty(input) && matcher.matches() ,"INVALID ORDER BY COLUMN %s",input);
		return input;
	}

	/**
	 * 检查逻辑操作符的合法性
	 * @param input
	 * @return input always
	 */
	private static String validLogicOperator(String input){
		input = nullToEmpty(input).trim();
		checkArgument(!isNullOrEmpty(input) && Pattern.compile("AND|OR",Pattern.CASE_INSENSITIVE).matcher(input).matches()
				," INVALID logic operator [%s],'AND' or 'OR' required",input);
		return input;
	}

	/**
	 * 加载指定的bsh脚本模板资源
	 * @param tmpl
	 * @return bsh脚本模板
	 */
	private static String loadTemplate(String tmpl){
		URL url = checkNotNull(WhereHelper.class.getResource(tmpl),"not found template %s", tmpl);
		try {
			return Resources.toString(url, Charsets.UTF_8);
		} catch (IOException e) {
			throw new RuntimeException(e);
		} 
	}
	/**
	 * 加载所有需要的bsh脚本模板数据
	 * @return ${模板名}--${脚本模板数据}的映射
	 */
	private static ImmutableMap<String, String> loadAllTemplates(){
		// 加载所有模板
		return  Maps.toMap(Sets.newHashSet(TMPL_EXP,TMPL_EQUAL,TMPL_BIT_TEST,TMPL_EQUAL_IF,TMPL_IF_ELSE,TMPL_LIKE,TMPL_COMPARE,TMPL_GROUP_BY,TMPL_ORDER_BY,TMPL_LIMIT,TMPL_BEFORE_COND,TMPL_AFTER_COND), 
				new Function<String, String>() {
					@Override
					public String apply(String input) {
						return loadTemplate("bsh_" + input);
					}
				});
	}
}